package unamur.iodass.catalog;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import unamur.iodass.communication.Communication;
import unamur.iodass.communication.messages.Book;
import unamur.iodass.communication.messages.BookStore;
import unamur.iodass.communication.messages.Catalog;
import unamur.iodass.communication.messages.LibraryRequest;
import unamur.iodass.registration.BookStoreHandler;

/**
 * 
 * Classe permettant d'enregistrer les catalog envoyés par les BookStore
 * 
 * @author Cherchem, marchal
 *
 */
public class RetreiveAllCatalogs {
	private static final Logger logger = Logger.getLogger(RetreiveAllCatalogs.class);

	private HashMap<Long, Book> saveBooks;

	private static volatile RetreiveAllCatalogs instance;

	public static RetreiveAllCatalogs getInstance() {
		if (instance == null) {
			synchronized (RetreiveAllCatalogs.class) {
				if (instance == null) {
					instance = new RetreiveAllCatalogs();
				}
			}
		}
		return instance;
	}

	private RetreiveAllCatalogs() {
		saveBooks = new HashMap<Long, Book>();
	}

	/**
	 * Ajoute le catalog provenant d'un bookstore, les doublons sont ignorés
	 * 
	 * @param catalog
	 */
	synchronized public void addCatalogue(Catalog catalog) {

		for (int i=0; i<catalog.getBooks().size(); i++) {

			Long isbn = Long.valueOf(catalog.getBooks().get(i).getIsbn());
			Book book = (Book) catalog.getBooks().get(i);

			book.setPrice(generateLibraryPrice());

			saveBooks.put(isbn, book);
		}
	}

	synchronized private void sendToBookStore_GetCatalog() {		

		ArrayList<BookStore> bookStores = BookStoreHandler.getInstance().getBookStores();

		for (int i=0; i<bookStores.size(); i++) {
			LibraryRequest libraryRequest = new LibraryRequest("GETCATALOG");
			Communication.getInstance().async(libraryRequest, bookStores.get(i).getIp(), bookStores.get(i).getPort());
		}

	}


	synchronized public int getSize() {
		return saveBooks.size();
	}

	synchronized public Book getBookByISBN(long isbn) {
		return saveBooks.get(isbn);
	}

	synchronized public ArrayList<Book> getBooksOfLibrary() {
		/*
		 * Reenvoyer une demande d'obtention des catalogs à tous les bookstores
		 */
		sendToBookStore_GetCatalog();

		Iterator iter = saveBooks.entrySet().iterator();
		ArrayList<Book> books = new ArrayList<Book>();

		while (iter.hasNext()){
			Map.Entry pairs = (Map.Entry)iter.next();
			books.add((Book)pairs.getValue());
		}

		return books;

	}

	private int generateLibraryPrice() {
		return 20 + (int)(Math.random() * ((30 - 20) + 1)); // [20..30]
	}



}
